import React, { useState, useEffect, useMemo } from 'react';
import { TreeSelect, TreeSelectProps } from 'antd';
import { api, xhrGet } from '@/services';
import { isValueEqual, transformValue } from '@/biz-components/_common/util';

const { SHOW_ALL } = TreeSelect;

interface RoleTreeProps<T = any> extends TreeSelectProps<T> {
  url: string;
  value?: any;
  placeholder?: string;
  treeCheckStrictly?: boolean;
  params?: any[];
  keyParams?: any[];
  rootParams?: any;
  treeCheckable?: boolean;
  changeKey?: string;
}

const RoleTreeSelect = (props: RoleTreeProps) => {
  const {
    url,
    value,
    placeholder = '请选择',
    onChange,
    params = ['parentId'],
    keyParams = ['id'],
    treeCheckStrictly = true,
    rootParams = {},
    treeCheckable = true,
    changeKey,
  } = props;

  const [treeData, setTreeData] = useState([]);

  const handleChange = (value: any, label: any, extra: any) => {
    const newValue = Array.isArray(value)
      ? value.map((item) => {
          return transformValue(item, changeKey);
        })
      : transformValue(value, changeKey);

    onChange?.(newValue, label, extra);
  };

  const onLoadData = async (treeNode?: any) => {
    if (!treeNode) {
      await xhrGet(url, rootParams).then((res: any) => {
        if (!res.success) {
          return;
        }
        if (res && res.result && res.result.length > 0) {
          res.result.map((item: any) => {
            item.title = item.name;
            item.pId = 0;
            item.value = item.code;
            if (item.type !== 'JOB') {
              item.disabled = true;
            }
            return item;
          });
          setTreeData(res.result);
        } else {
          // setTreeData([]);
        }
      });

      return;
    }
    const { id, code, type } = treeNode.props;
    const { length } = treeData.filter((item: any) => id === item.parentId);
    const data = [...treeData];
    if (length > 0) {
      return;
    }
    const parms: any = {};
    params.map((item: any, index: number) => {
      parms[item] = treeNode.props[keyParams[index]];
    });
    const res: any = await xhrGet(url, parms);
    if (!res.success) {
      return;
    }
    // @ts-ignore
    setTreeData(
      data.concat(
        res.result.map((item: any) => {
          item.pId = id;
          item.parentId = id;
          item.title = item.name;
          item.value = item.code;
          if (item.type !== 'JOB') {
            item.disabled = true;
          }
          return item;
        }),
      ),
    );
  };

  useEffect(() => {
    onLoadData();
  }, [url]);

  const displayValue = useMemo(() => {
    const data = treeData.concat([]);

    if (Array.isArray(value)) {
      return value.map((val: any) => {
        const record = data.find((item) =>
          isValueEqual(transformValue(item, changeKey), transformValue(val, changeKey)),
        );
        return record || val;
      });
    }
    return data.find((item) =>
      isValueEqual(transformValue(item, changeKey), transformValue(value, changeKey)),
    );
  }, [value, treeData]);

  if (displayValue && Array.isArray(displayValue)) {
    displayValue.map((vitem: any) => {
      if (!vitem.label) {
        vitem.label = vitem.name;
      }
      if (!vitem.value) {
        vitem.value = vitem.code;
      }
    });
  }

  return (
    <TreeSelect
      treeDataSimpleMode
      style={{ width: '100%' }}
      value={displayValue || []}
      dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
      placeholder={placeholder}
      onChange={handleChange}
      loadData={onLoadData}
      treeCheckable={treeCheckable}
      showCheckedStrategy={SHOW_ALL}
      treeCheckStrictly={treeCheckStrictly}
      treeData={treeData}
    />
  );
};

export default RoleTreeSelect;
